package com.innerclass;

/**
 * 演示匿名内部类的的使用
 */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}



class Outer04 { //外部类
    private int n1 = 10;//属性
    public void method() {//方法

        //1.需求：想使用IA接口，并创建对象
        //2.传统方式，写一个类，实现该接口，并创建对象
        //3.现在是不想创建实例该怎么写？？ 现在需求是Tiger只用一次，以后再也不用，这样定义了一个类很啰嗦
        //4.考虑匿名内部类来简化之
        //5.tiger的 编译类型 ？ IA
        //6.tiger的 运行类型 ？ 就是匿名内部类
        /*
            底层：
            class XXX implement IA {
                @Override
                public void cry() {
                    ......
                }
            }
         */
        //7.jdk底层在创建匿名内部类Outer04$1, 立马创建了实例Outer04$1, 并且把地址返回给了tiger
        // 返回给tiger
        //8.匿名内部类使用了一次就不能再使用
        //tiger 和 匿名内部类不是一回事， tiger可以反复使用。
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("tiger实现了cry");
            }

            //基于类的匿名内部类
            //分析
            //1.father编译类型 Father
            //2.father运行类型Outer$2

        };

        Father father = new Father("jack") {

            @Override
            public void test() {

                System.out.println("匿名内部类重写了test");
            }
        };

        Animal animal = new Animal() {

            @Override
            void eat() {
                System.out.println("实现了eat方法重写");
            }
        };

        //类名是Outer04$1
        System.out.println("tiger的运行类型是" + tiger.getClass());
        tiger.cry();

        System.out.println("father运行类型" + father.getClass());
        father.test();

        animal.eat();

//        new Tiger().cry();//传统

    }
}

interface IA {
    void cry();
}

//传统方式：
//class Tiger implements A {
//
//    @Override
//    public void cry() {
//        System.out.println("老虎类实现了cry方法");
//    }
//}

class Father {
    public Father(String name) {
    }

    public void test() {

    }
}

abstract class Animal {
    abstract void eat();
}
